`timescale 1ns/1ps

module tb_serializer();
    parameter N = 4;  // 每个输入数据包含4个字节（32位）
    
    reg clk;
    reg rst_n;
    reg [8*N-1:0] data;
    reg valid;
    wire [7:0] out_data;
    wire out_valid;
    
    // 实例化被测试模块
    serializer #(.N(N)) uut (
        .clk(clk),
        .rst_n(rst_n),
        .data(data),
        .valid(valid),
        .out_data(out_data),
        .out_valid(out_valid)
    );
    
    // 时钟生成（100MHz）
    always #5 clk = ~clk;
    
    // 测试序列
    initial begin
        // 初始化信号
        clk = 0;
        rst_n = 0;
        data = 0;
        valid = 0;
        
        // 复位
        #20;
        rst_n = 1;
        #10;
        
        // 测试1：单次传输
        $display("Test 1: Single transfer");
        data = 32'hAABBCCDD;
        valid = 1;
        #10;
        valid = 0;
        
        // 等待传输完成
        wait(out_valid == 0);
        #20;
        
        // 测试2：连续两次传输（无间隔）
        $display("Test 2: Back-to-back transfers");
        data = 32'h11223344;
        valid = 1;
        #10;
        data = 32'h55667788;
        #10;
        valid = 0;
        
        // 等待传输完成
        wait(out_valid == 0);
        #20;
        
        // 测试3：部分传输后插入新数据
        $display("Test 3: Interrupted transfer");
        data = 32'hDEADBEEF;
        valid = 1;
        #10;
        data = 32'hCAFEBABE;  // 在第一个数据未完成时输入新数据
        #10;
        valid = 0;
        
        // 等待传输完成
        wait(out_valid == 0);
        #20;
        
        // 测试4：复位测试
        $display("Test 4: Reset during transfer");
        data = 32'h12345678;
        valid = 1;
        #10;
        valid = 0;
        #15;  // 在传输过程中复位
        rst_n = 0;
        #20;
        rst_n = 1;
        
        // 完成测试
        #100;
        $display("All tests completed");
        $finish;
    end
    
    // 监控输出
    always @(posedge clk) begin
        if (out_valid) begin
            $display("Time=%0t: Output byte = %h", $time, out_data);
        end
    end
    
    // 记录波形（用于ModelSim）
    initial begin
        $dumpfile("wave.vcd");
        $dumpvars(0, tb_serializer);
    end
endmodule